package com.lvmama.service.dw.impl;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import lombok.extern.slf4j.Slf4j;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.lvmama.common.enums.NewCategoryEnum;
import com.lvmama.common.result.CodeMessage;
import com.lvmama.common.result.Result;
import com.lvmama.common.utils.DateUtil;
import com.lvmama.dao.dw.RepurchaseDao;
import com.lvmama.pojo.dto.dw.RepruchaseAnalysisQuery;
import com.lvmama.pojo.dto.dw.RepurchaseCategoryDTO;
import com.lvmama.pojo.dto.dw.RepurchaseRateDTO;
import com.lvmama.pojo.entity.dw.RepruchaseAnalysis;
import com.lvmama.service.dw.RepurchaseService;

/**
 * @Author:xuzhongwei
 * @Description:
 * @Date：2018/08/06
 */
@Slf4j
@Service
public class RepurchaseServiceImpl implements RepurchaseService {
	@Autowired
	private RepurchaseDao repurchaseDao;

	@Override
	public Result<List<RepruchaseAnalysis>> queryRepruchaseAnalysisList(RepruchaseAnalysisQuery query) {
		log.info("queryRepruchaseAnalysisList start, query:" + query);

		try {
			List<RepruchaseAnalysis> repruchaseAnalysisList = repurchaseDao.queryRepruchaseAnalysisList(query);
			return Result.success(repruchaseAnalysisList);
		} catch (Exception e) {
			log.error("queryRepruchaseAnalysisList error:" + e.getMessage());
		    return Result.error(CodeMessage.SERVER_ERROR);
		}
	}

	@Override
	public Result<RepruchaseAnalysis> selectLatestRecord() {
		log.info("selectLatestRecord start.");
		try {
			RepruchaseAnalysis repruchaseAnalysis = repurchaseDao.selectLatestRecord();
			return Result.success(repruchaseAnalysis);
		} catch (Exception e) {
			log.error("selectLatestRecord error:" + e.getMessage());
		    return Result.error(CodeMessage.SERVER_ERROR);
		}
	}

	@Override
	public Result<List<RepruchaseAnalysis>> getCreateTimeList(){
		try {
			List<RepruchaseAnalysis> repruchaseAnalysisList = this.repurchaseDao.getCreateTimeList();
			return Result.success(repruchaseAnalysisList);
		} catch (Exception e) {
			log.error("getCreateTimeList error:" + e.getMessage());
		    return Result.error(CodeMessage.SERVER_ERROR);
		}
	}

	@Override
	public Result<Map<String, Object>> getDistributionResult(String chooseTime) {
		
		Map<String, Object> resultMap = new HashMap<String, Object>();
		RepruchaseAnalysisQuery query = new RepruchaseAnalysisQuery();
		Date createTime = null;
	        
        if (!StringUtils.isEmpty(chooseTime)){
            createTime = DateUtil.parse(chooseTime, DateUtil.PATTERN_yyyy_MM_dd);
        	query.setCreateTime(createTime);
        }
	        
        if (createTime == null){
            //查询最近记录
            RepruchaseAnalysis repruchaseAnalysis = selectLatestRecord().getData();
            createTime = repruchaseAnalysis.getCreateTime();
            query.setCreateTime(repruchaseAnalysis.getCreateTime());
        }
        
		List<RepruchaseAnalysis> repruchaseAnalysisList = queryRepruchaseAnalysisList(query).getData();
		List<RepurchaseCategoryDTO> repurchaseCategoryList = setAnalysisList(repruchaseAnalysisList);;
		
        //101
        RepurchaseCategoryDTO lastMonthUser = getPurchaseCategoryByBusinessType(NewCategoryEnum.LAST_MONTH_USER.getCode(), query.getCreateTime());
        lastMonthUser.setCategoryType(NewCategoryEnum.LAST_MONTH_USER.getValue());
        //103
        RepurchaseCategoryDTO other = getPurchaseCategoryByBusinessType(NewCategoryEnum.OTHER_REPURCHASE.getCode(), query.getCreateTime());
        other.setCategoryType(NewCategoryEnum.OTHER_REPURCHASE.getValue());
        //104
        RepurchaseCategoryDTO up = getPurchaseCategoryByBusinessType(NewCategoryEnum.UP_REPURCHASE_USER.getCode(), query.getCreateTime());
        up.setCategoryType(NewCategoryEnum.UP_REPURCHASE_USER.getValue());
        repurchaseCategoryList.add(other);
        repurchaseCategoryList.add(up);
        
        resultMap.put("repurchaseCategories", repurchaseCategoryList);
        resultMap.put("categories", NewCategoryEnum.getTableShowNameEnum());
        resultMap.put("lastMonthUser", lastMonthUser);
      //计算复购率矩阵
        List<RepurchaseCategoryDTO> repurchaseCategoryRateList = setCategoryRateList(repurchaseCategoryList, lastMonthUser);
        resultMap.put("repurchaseCategoriesRate", repurchaseCategoryRateList);
		return Result.success(resultMap);
	}
	
	private List<RepurchaseCategoryDTO> setCategoryRateList(List<RepurchaseCategoryDTO> repurchaseCategoryList, RepurchaseCategoryDTO lastMonthUser){
		List<RepurchaseCategoryDTO> repurchaseCategoryRateList = new ArrayList<>();
		for (RepurchaseCategoryDTO repurchaseCategory : repurchaseCategoryList) {
            RepurchaseCategoryDTO repurchaseCategoryRate = new RepurchaseCategoryDTO();
            repurchaseCategoryRate.setCategoryType(repurchaseCategory.getCategoryType());
            repurchaseCategoryRate.setDomesticTicket(divide(repurchaseCategory.getDomesticTicket(), lastMonthUser.getDomesticTicket()));
            repurchaseCategoryRate.setOverseasTicket(divide(repurchaseCategory.getOverseasTicket(), lastMonthUser.getOverseasTicket()));
            repurchaseCategoryRate.setHotel(divide(repurchaseCategory.getHotel(), lastMonthUser.getHotel()));
            repurchaseCategoryRate.setHotelTicket(divide(repurchaseCategory.getHotelTicket(), lastMonthUser.getHotelTicket()));
            repurchaseCategoryRate.setLongGroup(divide(repurchaseCategory.getLongGroup(), lastMonthUser.getLongGroup()));
            repurchaseCategoryRate.setAroundGroup(divide(repurchaseCategory.getAroundGroup(), lastMonthUser.getAroundGroup()));
            repurchaseCategoryRate.setFreeWalker(divide(repurchaseCategory.getFreeWalker(), lastMonthUser.getFreeWalker()));
            repurchaseCategoryRate.setOverseasGroup(divide(repurchaseCategory.getOverseasGroup(), lastMonthUser.getOverseasGroup()));
            repurchaseCategoryRate.setOverseasFreeWalker(divide(repurchaseCategory.getOverseasFreeWalker(), lastMonthUser.getOverseasFreeWalker()));
            repurchaseCategoryRate.setOverseasCruiseShip(divide(repurchaseCategory.getOverseasCruiseShip(), lastMonthUser.getOverseasCruiseShip()));
            repurchaseCategoryRate.setOverseasOther(divide(repurchaseCategory.getOverseasOther(), lastMonthUser.getOverseasOther()));
            repurchaseCategoryRate.setTrainTicket(divide(repurchaseCategory.getTrainTicket(), lastMonthUser.getTrainTicket()));
            repurchaseCategoryRate.setAirTicket(divide(repurchaseCategory.getAirTicket(), lastMonthUser.getAirTicket()));
            repurchaseCategoryRate.setDownRepurchaseUser(divide(repurchaseCategory.getDownRepurchaseUser(), lastMonthUser.getDownRepurchaseUser()));
            repurchaseCategoryRateList.add(repurchaseCategoryRate);
        }
		return repurchaseCategoryRateList;
	}
	
	private List<RepurchaseCategoryDTO>  setAnalysisList(List<RepruchaseAnalysis> repruchaseAnalysisList){
		List<RepurchaseCategoryDTO> repurchaseCategoryList = new ArrayList<>();
		for (NewCategoryEnum en : NewCategoryEnum.values()) {
            if (null != en.getShowName()) {
                RepurchaseCategoryDTO category = new RepurchaseCategoryDTO();
                category.setCategoryType(en.getShowName());
                for (RepruchaseAnalysis re : repruchaseAnalysisList) {
                    if (en.getValue().equals(re.getCategory())) {
                        switch (re.getBusinessType()) {
                            case "01":
                                category.setDomesticTicket(re.getNum());
                                break;
                            case "02":
                                category.setOverseasTicket(re.getNum());
                                break;
                            case "04":
                                category.setHotel(re.getNum());
                                break;
                            case "05":
                                category.setHotelTicket(re.getNum());
                                break;
                            case "06":
                                category.setLongGroup(re.getNum());
                                break;
                            case "07":
                                category.setAroundGroup(re.getNum());
                                break;
                            case "08":
                                category.setFreeWalker(re.getNum());
                                break;
                            case "09":
                                category.setOverseasGroup(re.getNum());
                                break;
                            case "10":
                                category.setOverseasFreeWalker(re.getNum());
                                break;
                            case "11":
                                category.setOverseasCruiseShip(re.getNum());
                                break;
                            case "12":
                                category.setOverseasOther(re.getNum());
                                break;
                            case "98":
                                category.setTrainTicket(re.getNum());
                                break;
                            case "99":
                                category.setAirTicket(re.getNum());
                                break;
                            case "102":
                                category.setDownRepurchaseUser(re.getNum());
                                break;
                        }
                    }
                }
                repurchaseCategoryList.add(category);
            }
		}
		return repurchaseCategoryList;
	}
	
	private RepurchaseCategoryDTO getPurchaseCategoryByBusinessType(String businessType, Date createTime) {
        RepruchaseAnalysisQuery query = new RepruchaseAnalysisQuery();
        query.setCreateTime(createTime);
        query.setBusinessType(businessType);
        List<RepruchaseAnalysis> repruchaseAnalysisList = queryRepruchaseAnalysisList(query).getData();
        RepurchaseCategoryDTO lastMonthUser = new RepurchaseCategoryDTO();
        for (RepruchaseAnalysis re : repruchaseAnalysisList) {
            NewCategoryEnum categoryEnum = NewCategoryEnum.getEnumByValue(re.getCategory());
            if (null != categoryEnum) {
                switch (categoryEnum) {
                    case DOMESTIC_TICKET:
                        lastMonthUser.setDomesticTicket(re.getNum());
                        break;
                    case OVERSEAS_TICKET:
                        lastMonthUser.setOverseasTicket(re.getNum());
                        break;
                    case HOTEL:
                        lastMonthUser.setHotel(re.getNum());
                        break;
                    case HOTEL_TICKET:
                        lastMonthUser.setHotelTicket(re.getNum());
                        break;
                    case LONG_GROUP:
                        lastMonthUser.setLongGroup(re.getNum());
                        break;
                    case AROUND_GROUP:
                        lastMonthUser.setAroundGroup(re.getNum());
                        break;
                    case FREE_WALKER:
                        lastMonthUser.setFreeWalker(re.getNum());
                        break;
                    case OVERSEAS_GROUP:
                        lastMonthUser.setOverseasGroup(re.getNum());
                        break;
                    case OVERSEAS_FREE_WALKER:
                        lastMonthUser.setOverseasFreeWalker(re.getNum());
                        break;
                    case OVERSEAS_CRUISE_SHIP:
                        lastMonthUser.setOverseasCruiseShip(re.getNum());
                        break;
                    case OVERSEAS_OTHER:
                        lastMonthUser.setOverseasOther(re.getNum());
                        break;
                    case TRAIN_TICKET:
                        lastMonthUser.setTrainTicket(re.getNum());
                        break;
                    case AIR_TICKET:
                        lastMonthUser.setAirTicket(re.getNum());
                        break;
				default:
					break;

                }
            }
        }
        if (NewCategoryEnum.OTHER_REPURCHASE.getCode().equals(businessType)) {
            lastMonthUser.setDownRepurchaseUser("");
        } else if (NewCategoryEnum.LAST_MONTH_USER.getCode().equals(businessType)) {
            //查询上月下单用户总数
            RepruchaseAnalysisQuery queryLastSum = new RepruchaseAnalysisQuery();
            queryLastSum.setCreateTime(createTime);
            queryLastSum.setBusinessType(NewCategoryEnum.LAST_MONTH_USER_ALL.getCode());
            List<RepruchaseAnalysis> lastSumList = queryRepruchaseAnalysisList(queryLastSum).getData();
            if (null != lastSumList && !lastSumList.isEmpty()) {
                String num = lastSumList.get(0).getNum();
                lastMonthUser.setDownRepurchaseUser(StringUtils.isNotBlank(num) ? num : "0");
            }
        } else if (NewCategoryEnum.UP_REPURCHASE_USER.getCode().equals(businessType)) {
            //查询上游复购用户总数
            RepruchaseAnalysisQuery queryUpSum = new RepruchaseAnalysisQuery();
            queryUpSum.setCreateTime(createTime);
            queryUpSum.setBusinessType(NewCategoryEnum.UP_REPURCHASE_USER_ALL.getCode());
            List<RepruchaseAnalysis> upSumList = queryRepruchaseAnalysisList(queryUpSum).getData();
            if (null != upSumList && !upSumList.isEmpty()) {
                String num = upSumList.get(0).getNum();
                lastMonthUser.setDownRepurchaseUser(StringUtils.isNotBlank(num) ? num : "0");
            }
        }
        return lastMonthUser;
    }

    private String divide(String num1, String num2) {
        if (StringUtils.isBlank(num1) || StringUtils.isBlank(num2) || "0".equals(num1) || "0".equals(num2)) {
            return "0.00%";
        }
        BigDecimal num = new BigDecimal(num1).multiply(new BigDecimal("100")).divide(new BigDecimal(num2), 2, BigDecimal.ROUND_HALF_UP);
        //格式化
        DecimalFormat fm = new DecimalFormat("0.00");
        return fm.format(num) + "%";
    }

	@Override
	public Result<Map<String, Object>> getAttributesResult(String chooseTime) {
		
		Map<String, Object> resultMap = new HashMap<String, Object>();
		 // 初始化列表
        List<RepurchaseRateDTO> repurchaseRateList = new ArrayList<>();
        for (NewCategoryEnum en : NewCategoryEnum.values()) {
            if (StringUtils.isNotEmpty(en.getShowName())) {
                RepurchaseRateDTO vo = new RepurchaseRateDTO();
                vo.setCategoryName(en.getValue());
                vo.setCateforyShowName(en.getShowName());
                repurchaseRateList.add(vo);
            }
        }

        RepruchaseAnalysisQuery query = new RepruchaseAnalysisQuery();

        if (!StringUtils.isEmpty(chooseTime)){
            query.setCreateTime(DateUtil.parse(chooseTime, DateUtil.PATTERN_yyyy_MM_dd));
        }else {
        	// 查询最近记录
        	RepruchaseAnalysis repruchaseAnalysis = selectLatestRecord().getData();
            query.setCreateTime(repruchaseAnalysis.getCreateTime());
        }
        // 上游复购率
        query.setBusinessType(NewCategoryEnum.UP_REPURCHASE_RATE.getCode());
        List<RepruchaseAnalysis> upRepurchaseRateList = queryRepruchaseAnalysisList(query).getData();
        for (RepruchaseAnalysis upRepurchaseRate : upRepurchaseRateList) {
            for (RepurchaseRateDTO vo : repurchaseRateList) {
                if (vo.getCategoryName().equals(upRepurchaseRate.getCategory())) {
                    vo.setUpRepurchaseRate(new BigDecimal(upRepurchaseRate.getNum()).multiply(new BigDecimal("100")).toString());
                }
            }
        }

        // 下游复购率
        query.setBusinessType(NewCategoryEnum.DOWN_REPURCHASE_RATE.getCode());
        List<RepruchaseAnalysis> downRepurchaseRateList = queryRepruchaseAnalysisList(query).getData();
        for (RepruchaseAnalysis downRepurchaseRate : downRepurchaseRateList) {
            for (RepurchaseRateDTO vo : repurchaseRateList) {
                if (vo.getCategoryName().equals(downRepurchaseRate.getCategory())) {
                    vo.setDownRepurchaseRate(new BigDecimal(downRepurchaseRate.getNum()).multiply(new BigDecimal("100")).toString());
                }
            }
        }

        // 自复购率
        query.setBusinessType(NewCategoryEnum.SELF_REPURCHASE_RATE.getCode());
        List<RepruchaseAnalysis> selfRepurchaseRateList = queryRepruchaseAnalysisList(query).getData();
        for (RepruchaseAnalysis selfRepurchaseRate : selfRepurchaseRateList) {
            for (RepurchaseRateDTO vo : repurchaseRateList) {
                if (vo.getCategoryName().equals(selfRepurchaseRate.getCategory())) {
                    vo.setSelfRepurchaseRate(new BigDecimal(selfRepurchaseRate.getNum()).multiply(new BigDecimal("100")).toString());
                }
            }
        }

        // 交叉复购率
        query.setBusinessType(NewCategoryEnum.ACROSS_REPURCHASE_RATE.getCode());
        List<RepruchaseAnalysis> acrossRepurchaseRateList = queryRepruchaseAnalysisList(query).getData();
        for (RepruchaseAnalysis acrossRepurchaseRate : acrossRepurchaseRateList) {
            for (RepurchaseRateDTO vo : repurchaseRateList) {
                if (vo.getCategoryName().equals(acrossRepurchaseRate.getCategory())) {
                    vo.setAcrossRepurchaseRate(new BigDecimal(acrossRepurchaseRate.getNum()).multiply(new BigDecimal("100")).toString());
                }
            }
        }

        List<String> chart1List = new ArrayList<>();
        List<String> chart2List = new ArrayList<>();

        for (RepurchaseRateDTO vo : repurchaseRateList) {
            String chart1 = "[" + vo.getUpRepurchaseRate() + "," + vo.getDownRepurchaseRate() + ", 30 ,\'" + vo.getCateforyShowName() + "\',001]";
            chart1List.add(chart1);
            String chart2 = "[" + vo.getSelfRepurchaseRate() + "," + vo.getAcrossRepurchaseRate() + ", 30 ,\'" + vo.getCateforyShowName() + "\',002]";
            chart2List.add(chart2);
        }
        resultMap.put("repurchaseChart1", Arrays.deepToString(chart1List.toArray()));
        resultMap.put("repurchaseChart2", Arrays.deepToString(chart2List.toArray()));
        return Result.success(resultMap);
	}
}
